package cn.buk.tms.eotms.dao;

import cn.buk.common.sc.Page;
import cn.buk.common.util.DateUtil;
import cn.buk.tms.eotms.dao.factory.OperationLogFactory;
import cn.buk.tms.eotms.entity.FlightChangeOrder;
import cn.buk.tms.eotms.entity.FlightChangeOrder_;
import cn.buk.tms.eotms.entity.OperationLog;
import cn.buk.tms.eotms.sc.SearchFlightOrderCriteria;
import org.springframework.stereotype.Component;

import jakarta.persistence.criteria.*;
import jakarta.transaction.Transactional;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yfdai
 */
@Component
@Transactional
public class ChangeOrderDaoImpl extends AbstractDao implements ChangeOrderDao {

  @Override
  public List<FlightChangeOrder> searchFlightChangeOrder(final int ownerId, final int customerId,
      SearchFlightOrderCriteria sc) {
    List<FlightChangeOrder> results = null;

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<FlightChangeOrder> cq = cb.createQuery(FlightChangeOrder.class);
    Root<FlightChangeOrder> root = cq.from(FlightChangeOrder.class);
    root.alias("o");

    var predicates0 = getPredicates_searchFlightChangeOrder(ownerId, customerId, sc, cb, root);

    //计算根据条件查询得出的数据总数
    CriteriaQuery<Long> countQuery = cb.createQuery(Long.class);
    Root<FlightChangeOrder> countRoot = countQuery.from(FlightChangeOrder.class);
    countRoot.alias("o");

    var predicates1 = getPredicates_searchFlightChangeOrder(ownerId, customerId, sc, cb, countRoot);

    countQuery.select(cb.count(countRoot))
        .where(predicates1.toArray(new Predicate[predicates1.size()]));
    Long count = em.createQuery(countQuery).getSingleResult();

    int maxResults = count.intValue();
    if (maxResults > 0) {
      cq.where(predicates0.toArray(new Predicate[predicates0.size()]));
      List<jakarta.persistence.criteria.Order> orderByes = new ArrayList<>();
      orderByes.add(cb.desc(root.get("id")));

      cq.orderBy(orderByes);

      Page page = sc.getPage();
      page.setRowCount(maxResults);
      int i = (page.getPageNo() - 1) * page.getPageSize();

      if (i < 0) {
        i = 0;
      }

      results = em.createQuery(cq)
          .setFirstResult(i)
          .setMaxResults(page.getPageSize()).getResultList();
    }

    if (results == null) {
      results = new ArrayList<>();
    }

    return results;
  }

  private List<Predicate> getPredicates_searchFlightChangeOrder(int ownerId, int customerId, SearchFlightOrderCriteria sc, CriteriaBuilder cb, Root<FlightChangeOrder> root) {
    List<Predicate> predicates = new ArrayList<>();

    Predicate predicate = cb.conjunction();
    predicates.add(predicate);

    predicate = cb.equal(root.get(FlightChangeOrder_.enterpriseId), ownerId);
    predicates.add(predicate);


    predicate = cb.equal(root.get(FlightChangeOrder_.customerId), customerId);
    predicates.add(predicate);


    if (sc.getBalCode() != null && sc.getTicketNo() != null) {
      if (sc.getBalCode().length() == 3 && sc.getTicketNo().length() == 10) {
        predicate = cb.equal(root.get(FlightChangeOrder_.balanceCode), sc.getBalCode());
        predicates.add(predicate);

        predicate = cb.equal(root.get(FlightChangeOrder_.ticketNo), sc.getTicketNo());
        predicates.add(predicate);
      }
    }

    if (sc.getIntlTicket() > -1) {
      predicate = cb.equal(root.get(FlightChangeOrder_.intlTicket), sc.getIntlTicket());
      predicates.add(predicate);
    }

    if (sc.getName() != null && sc.getName().trim().length() > 0) {
      predicate = cb.like(root.get(FlightChangeOrder_.psgName), "%" + sc.getName().trim() + "%");
      predicates.add(predicate);
    }

    if (sc.getIdno() != null && sc.getIdno().trim().length() > 0) {
      predicate = cb.like(root.get(FlightChangeOrder_.idNo), "%" + sc.getIdno().trim() + "%");
      predicates.add(predicate);
    }

    if (sc.getStatus() > -1) {
      predicate = cb.equal(root.get(FlightChangeOrder_.status), sc.getStatus());
      predicates.add(predicate);
    }

    if (sc.getTicketNo().length() > 0) {
      String temp = sc.getTicketNo().trim();
      if (temp.length() >= 10) {
        temp = temp.substring(temp.length() - 10);

        predicate = cb.equal(root.get(FlightChangeOrder_.ticketNo), temp);
        predicate = cb.or(predicate, cb.like(root.get(FlightChangeOrder_.newTicketNo), "%" + temp + "%"));
      } else {
        predicate = cb.like(root.get(FlightChangeOrder_.ticketNo), "%" + temp + "%");
        predicate = cb.or(predicate, cb.like(root.get(FlightChangeOrder_.newTicketNo), "%" + temp + "%"));

      }
      predicates.add(predicate);
    }

    if (sc.getBeginDate() != null) {
      predicate = cb.greaterThanOrEqualTo(root.get(FlightChangeOrder_.createTime), sc.getBeginDate());
      predicates.add(predicate);
    }

    if (sc.getEndDate() != null) {
      predicate = cb.lessThanOrEqualTo(root.get(FlightChangeOrder_.createTime),
          DateUtil.addDays(sc.getEndDate(), 1));
      predicates.add(predicate);
    }

    if (sc.getOrderNo().length() > 0) {
      predicate = cb.equal(root.get(FlightChangeOrder_.orderNo), sc.getOrderNo());
      predicates.add(predicate);
    }

    if (sc.getChangeOrderNo().length() > 0) {
      predicate = cb.equal(root.get(FlightChangeOrder_.changeOrderNo), sc.getChangeOrderNo());
      predicates.add(predicate);
    }

    if (sc.getOp1().length() > 0) {
      //查找指定用户名的订单
      predicate = cb.equal(root.get(FlightChangeOrder_.operator), sc.getOp1());
      predicates.add(predicate);
    }
    if (sc.getDepartmentId() != null) {
      //只查找本部门的
      List<String> usernames = doGetCustomerDepartmentOperator(ownerId, customerId, sc.getDepartmentId());


      Path<String> path = root.get(FlightChangeOrder_.operator);
      CriteriaBuilder.In<String> in = cb.in(path);
      for(String username: usernames) {
        in.value(username);
      }

      predicates.add(in);
    }
    return predicates;
  }

  @Override
  public List<FlightChangeOrder> searchByFlightOrderNo(int ownerId, String orderNo) {
    return em.createQuery("select o from FlightChangeOrder o "
        + "where o.enterpriseId = :enterpriseId and o.orderNo = :orderNo order by o.ticketNo", FlightChangeOrder.class)
        .setParameter("enterpriseId", ownerId)
        .setParameter("orderNo", orderNo)
        .getResultList();
  }

  @Override
  public FlightChangeOrder getFlightChangeOrderDetail(int id) {
    return em.find(FlightChangeOrder.class, id);
  }

  @Override
  public int createFlightChangeOrder(FlightChangeOrder info) {
    int retCode = 0;

    em.persist(info);

    retCode = info.getId();
    if (retCode > 0) {
      OperationLog log = createFlightChangeOrderLog(info.getEnterpriseId(), info.getOperator(),
              retCode, "创建改签单");
      em.persist(log);
    }

    return retCode;
  }

  private OperationLog createFlightChangeOrderLog(int enterpriseId, String username,
                                                  int refundOrderId, String remark) {
    OperationLog log = OperationLogFactory.createFlightChangeOrderOperationLog();
    log.setEnterpriseId(enterpriseId);
    log.setOperator(username);
    log.setOrderId(refundOrderId);
    log.setContent(remark);

    return log;
  }

}
